home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / bogoupgrade-bdb < prev    next >
Text File  |  2009-06-05  |  6KB  |  250 lines

  1. #! /usr/bin/perl -w
  2.  
  3. =pod
  4.  
  5. =head1 NAME
  6.  
  7. bogoupgrade -- upgrade a bogofilter database to current version.
  8.  
  9. =cut
  10.  
  11. # bogofilter-0.3 through bogofilter-0.6.3
  12. #
  13. #    HEADER "# bogofilter email-count (format version A): %lu"
  14. #
  15.  
  16. # bogofilter-0.7.x
  17. #
  18. #    HEADER "# bogofilter email-count (format version B): %lu"
  19. #
  20.  
  21. # bogofilter-0.8 to bogofilter-0.13.x
  22. #
  23. # BerkeleyDB with double wordlists 
  24. #    spamlist.db and goodlist.db
  25.  
  26. # bogofilter-0.14 and later
  27. #
  28. # BerkeleyDB with single wordlist
  29. #    wordlist.db
  30.  
  31. require 5.005_03;
  32. use strict;
  33. use filetest 'access';
  34. use Pod::Usage;
  35.  
  36. sub convert_double_to_single();
  37. sub convert_format_A();
  38. sub convert_format_B();
  39. sub db_verify($);
  40.  
  41. my $VERSION = '0.5.0';
  42.  
  43. my ($in, $out, $dir, $yday, $msg_count_token);
  44.  
  45. my $bogoutil = 'bogoutil';
  46.  
  47. for (my $i = 0; $i < @ARGV; $i++){
  48.   my $arg = $ARGV[$i];
  49.  
  50.   if ($arg eq '-d'){
  51.     $dir = $ARGV[++$i];
  52.   } elsif ($arg eq '-i'){
  53.     $in = $ARGV[++$i];
  54.   } elsif ($arg eq '-o'){
  55.     $out = $ARGV[++$i];
  56.   } elsif ($arg eq '-b'){
  57.     $bogoutil = $ARGV[++$i];
  58.   } elsif ($arg eq '-y'){
  59.     $yday = "-y $ARGV[++$i]";
  60.   } elsif ($arg eq '-h' or $arg eq '--help'){
  61.     pod2usage(-verbose => 1, -exitstatus => 0);
  62.   } else {
  63.     pod2usage(-verbose => 0, -exitstatus => 1);
  64.   }
  65. }
  66.  
  67. my $db_ext = $ENV{DB_EXT} ||  'db';
  68.  
  69. if ($dir) {
  70.     if ($in || $out) {
  71.         pod2usage("Cannot use -d at the same time as -i or -o!");
  72.     }
  73.     convert_double_to_single();
  74. } else {
  75.     pod2usage("Missing input filename.\nAborting") unless $in;
  76.     pod2usage("Missing output filename.\nAborting") unless $out;
  77.  
  78.     my $msg_count_token = '.MSG_COUNT';
  79.  
  80.     open(F, "< $in") or die "Cannot open input file [$in]. $!.\nAborting";
  81.     my $sig = <F>;
  82.     chomp($sig);
  83.     if ($sig =~ m/^\# bogofilter wordlist \(format version A\):\s(\d+)$/){ 
  84.     convert_format_A();
  85.     }
  86.     elsif ($sig =~ m/^\# bogofilter email-count \(format version B\):\s(\d+)/){
  87.     convert_format_B();
  88.     }
  89.     else {
  90.     $sig =~ y/[\040-\177]/_/cs;
  91.     warn "Cannot recognize signature [$sig].\n";
  92.     exit(2);
  93.     }
  94. }
  95.  
  96. sub db_verify($) {
  97.     my ($f) = shift;
  98.     if (!-r $f) {
  99.         die "Database $f is not readable: $!\nAborting";
  100.     }
  101.     my $ret = system ($bogoutil, '--db-verify', $f);
  102.     die "Database $f is corrupt.\nAborting" if $ret;
  103. }
  104.  
  105. sub convert_format_A() {  
  106.   my $msg_count = $1;
  107.   my $cmd = "$bogoutil $yday -l $out";
  108.   open(OUT, "| $cmd") or die "Cannot run command \"$cmd\": $!\nAborting";
  109.   while(<F>){
  110.     print OUT $_;
  111.   }
  112.   print OUT "$msg_count_token $msg_count\n";
  113.   close(OUT) or die "Error executing command \"$cmd\": $!\nAborting";
  114.   close(F);
  115. }
  116.  
  117. sub convert_format_B() {
  118.   my $msg_count = $1;
  119.   my $in_db = $in;
  120.  
  121.   $in_db =~ s/count$/$db_ext/;
  122.  
  123.   unless (-f $in_db){
  124.     warn("Cannot find database file [$in_db]\n  corresponding to input file [$in]\n");
  125.     exit;
  126.   }
  127.  
  128.   my $cmd = "$bogoutil $yday -l $out";
  129.   open(OUT, "| $cmd") or die "Cannot run command \"$cmd\": $!\nAborting";
  130.  
  131.   close(F);
  132.   db_verify($in_db);
  133.   $cmd = "$bogoutil $yday -d $in_db";
  134.   open(F, "$cmd |") or die "Cannot run command \"$cmd\": $!\nAborting";
  135.  
  136.   while(<F>){
  137.     if (m/^\.count\s+(\d+)$/){
  138.       warn("Found a message count of [$1] in db.\nThrowing away text file count of [$msg_count]\n");
  139.       $msg_count = $1;
  140.       next;
  141.     }
  142.     elsif (/^$msg_count_token\s(\d+)$/){
  143.       warn("This database appears to have been upgraded already.\nBut there's no harm in doing it again.\n");
  144.       $msg_count = $1;
  145.       next;
  146.     }
  147.     print OUT $_;
  148.   }
  149.   print OUT "$msg_count_token $msg_count\n";
  150.  
  151.   close(F);
  152.   close(OUT);
  153. }
  154.  
  155. # args: filename format
  156. sub cvt2to1_get($$) {
  157.     my ($filename, $format) = @_;
  158.     my @tmp;
  159.     my $cmd;
  160.  
  161.     die "need array context in cvs2to1_get.\nAborting" unless wantarray;
  162.     db_verify($filename);
  163.     $cmd = "$bogoutil -d $filename";
  164.     open(I, "$cmd |") or die "cannot run \"$cmd\": $!\nAborting";
  165.     while (<I>) {
  166.     chomp;
  167.     my @a = split;
  168.     push @tmp, sprintf($format, $a[0], $a[1], $a[2]);
  169.     }
  170.     close I or die "error running \"$cmd\": $!\nAborting";
  171.     return @tmp;
  172. }
  173.  
  174. sub convert_double_to_single() {
  175.     my @tmp;
  176.  
  177.     my $word = "$dir/wordlist.$db_ext";
  178.     my $spam = "$dir/spamlist.$db_ext";
  179.     my $good = "$dir/goodlist.$db_ext";
  180.  
  181.     if (-e $word) { die "$word already exists.\nAborting"; }
  182.  
  183.     push @tmp, cvt2to1_get($spam, "%s %d 0 %d");
  184.     push @tmp, cvt2to1_get($good, "%s 0 %d %d");
  185.     my $cmd = "$bogoutil -l $word";
  186.     open(O, "| $cmd") or die "cannot run \"$cmd\": $!\nAborting";
  187.     print O join("\n", sort @tmp), "\n";
  188.     close O or die "error executing \"$cmd\": $!\nAborting";
  189. }
  190.  
  191. exit(0);
  192.  
  193. __END__
  194. =pod
  195.  
  196. =head1 SYNOPSIS
  197.  
  198.  bogoupgrade [options] -d <bogofilter directory>
  199.  bogoupgrade [options] -i <input text file> -o <output db file>
  200.  bogoupgrade {-h|--help}
  201.  
  202.  Options:
  203.     -b <path to bogoutil>
  204.  
  205. =head1 DESCRIPTION
  206.  
  207. B<bogoupgrade> updates bogofilter databases from older formats to the current
  208. format.
  209.  
  210. =head1 OPTIONS
  211.  
  212. =over 8
  213.  
  214. =item B<-d <directory>>
  215.  
  216. Name of directory containing database files.  Old files will be read and new
  217. files will be written.
  218.  
  219. =item B<-i <input file>>
  220.  
  221. Text file containing message count, and possibly wordlist data records.  If the
  222. file only contains a message count but no word list records, there must be a
  223. database file, in the same directory as the text file, which contains the word
  224. list data.
  225.  
  226. =item B<-o <output file>>
  227.  
  228. Output database file.  Use the appropriate file extension for your version of
  229. bogofilter, i.e. '.db' for Berkeley DB and SQLite3, or '.qdbm' for QDBM.
  230.  
  231. =item B<-b <path to bogoutil program>>
  232.  
  233. Defaults to 'bogoutil', in the hopes that your shell will find it.
  234.  
  235. =item B<-h> | B<--help>
  236.  
  237. Print the help - you are currently reading it.
  238.  
  239. =back
  240.  
  241. =head1 AUTHORS
  242.  
  243.  Gyepi Sam <gyepi@praxis-sw.com>
  244.  David Relson <relson@osagesoftware.com>
  245.  Matthias Andree <matthias.andree@gmx.de>
  246.  
  247. =cut
  248.  
  249. # vim: set filetype=perl ai:
  250.